package com.example.service.impl;

import com.example.mapper.*;
import com.example.pojo.NcPojo;
import com.example.pojo.NcVarPojo;
import com.example.service.ReadNcService;
import com.example.util.MyConstants;
import com.example.util.StreamUtil;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import ucar.ma2.Array;
import ucar.nc2.*;
import ucar.nc2.dataset.NetcdfDataset;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;


@Service
public class ReadNcServiceImpl implements ReadNcService {

    @Resource
    private NcPrsMapper ncPrsMapper;

    @Resource
    private NcCdnMapper ncCdnMapper;


    public static NcPojo readNcFile1(String filePath) {
        int LEVEL = 0,HOUR=0;

        //生成100个待读取的坐标
        List<NcPojo> ncList = getNcList();

        List<NcVarPojo> results = new ArrayList<>();

        NetcdfFile nf = null;
        try {
            nf = NetcdfDataset.open("F:\\JT63XZCW_WRF10d_meter_202204060800_202204060800_202204160800.nc");

            Variable pressure = nf.findVariable("PRS");
            List<Dimension> dimensionsAll = pressure.getDimensionsAll();
            for (int i = 0; i < dimensionsAll.size(); i++) {
                Dimension dimension = dimensionsAll.get(i);
                if ("time".equals(dimension.getDODSName())) {
                    HOUR=dimension.getLength()-1;
                }else if ("level".equals(dimension.getDODSName())){
                    LEVEL=dimension.getLength()-1;
                }
            }
            for (int i = 0; i < ncList.size(); i++) {
                NcPojo ncPojo = ncList.get(i);
                for (int j = 0; j < LEVEL; j++) {
                    for (int k = 0; k < HOUR; k++) {
                        NcVarPojo varPojo = new NcVarPojo();
                        varPojo.setLat(ncPojo.getLat());
                        varPojo.setLon(ncPojo.getLon());
                        varPojo.setLevel(j);
                        varPojo.setTime(k);
                        String spec= new StringBuilder(Strings.EMPTY)
                                .append(varPojo.getTime())
                                .append(":")
                                .append(varPojo.getTime())
                                .append(",")
                                .append(varPojo.getLevel())
                                .append(":")
                                .append(varPojo.getLevel())
                                .append(",")
                                .append(varPojo.getLat())
                                .append(":")
                                .append(varPojo.getLat())
                                .append(",")
                                .append(varPojo.getLon())
                                .append(":")
                                .append(varPojo.getLon())
                                .toString();
                        Array read = pressure.read(spec);
                        Float v = null;
                        if (!read.toString().contains(",")){
                            v = Float.valueOf(read.toString());
                        }
                        varPojo.setValue(v);
                        results.add(varPojo);
                    }
                }
            }
            System.out.println(results.size());
            nf.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    //todo 入库操作昂
    private static List<NcPojo> getNcList(){
        Integer lonMax=78;
        Integer latMax=64;
        LinkedHashSet<NcPojo> set = new LinkedHashSet<>();
        Random random = new Random();
        do {
            Integer lon= random.nextInt(lonMax);
            Integer lat= random.nextInt(latMax);
            NcPojo ncPojo = new NcPojo();
            ncPojo.setLon(lon);
            ncPojo.setLat(lat);
            if (!set.contains(set)) {
                set.add(ncPojo);
            }
        }while (set.size()!=0&&set.size()<100);

        List<NcPojo> results=new ArrayList<>(set);
        return results;
    };

    public static void main(String[] args) throws IOException {
        NetcdfFile nf = null;
        nf = NetcdfDataset.open("F:\\JT63XZCW_WRF10d_meter_202204060800_202204060800_202204160800.nc");
        List<Variable> variables = nf.getVariables();

        Variable pressure = nf.findVariable("PRS");
        System.out.println(pressure.getFullNameEscaped());
        pressure.getDimensions();
    }

    @Resource
    private NcPre1hMapper ncPre1hMapper;

    @Resource
    private NcPre15mMapper ncPre15mMapper;

    @Resource
    private NcRhuMapper ncRhuMapper;

    @Resource
    private NcSrMapper ncSrMapper;

    @Resource
    private NcTemMapper ncTemMapper;

    @Resource
    private NcWdMapper ncWdMapper;

    @Resource
    private NcWsMapper ncWsMapper;

    private NcBaseMapper getMapperByFullName(String name){
        NcBaseMapper ncBaseMapper=null;
        switch (name){
            case MyConstants
                    .PRE_1H:ncBaseMapper=ncPre1hMapper;
                return ncBaseMapper ;
            case MyConstants
                    .PRE_15M:ncBaseMapper=ncPre15mMapper;
                return ncBaseMapper ;
            case MyConstants
                    .PRS:ncBaseMapper=ncPrsMapper;
                return ncBaseMapper ;
            case MyConstants
                    .SR:ncBaseMapper=ncSrMapper;
                return ncBaseMapper ;
            case MyConstants
                    .WD:ncBaseMapper=ncWdMapper;
                return ncBaseMapper ;
            case MyConstants
                    .WS:ncBaseMapper=ncWsMapper;
                return ncBaseMapper ;
            case MyConstants
                    .TEM:ncBaseMapper=ncTemMapper;
                return ncBaseMapper ;
            case MyConstants
                    .RHU:ncBaseMapper=ncRhuMapper;
                return ncBaseMapper ;
            default:ncBaseMapper = null;
        }
        return ncBaseMapper;
    }

    @Override
    public NcPojo readNcFile(String filePath) {
        long startTime = System.currentTimeMillis();
        int LEVEL = 1,HOUR=0;

        //生成100个待读取的坐标
        List<NcPojo> ncList = getNcList();
        ncCdnMapper.insertBatchAndReturnID(ncList);
        List<NcVarPojo> results = new ArrayList<>();

        NcBaseMapper ncBaseMapper=null;

        NetcdfFile nf = null;
        try {
            nf = NetcdfDataset.open("F:\\JT63XZCW_WRF10d_meter_202204060800_202204060800_202204160800.nc");
            List<Variable> variables = nf.getVariables();
            for (int v = 0; v < variables.size(); v++) {
                Boolean levelFlag=false;
                Variable variable = variables.get(v);
                String fullNameEscaped = variable.getFullNameEscaped().toLowerCase();
                List<Dimension> dimensionsAll = variable.getDimensionsAll();
                for (int i = 0; i < dimensionsAll.size(); i++) {
                    Dimension dimension = dimensionsAll.get(i);
                    if ("time".equals(dimension.getDODSName())) {
                        HOUR=dimension.getLength();
                    }else if ("level".equals(dimension.getDODSName())){
                        LEVEL=dimension.getLength();
                        levelFlag=true;
                    }
                }
                for (int i = 0; i < ncList.size(); i++) {
                    NcPojo ncPojo = ncList.get(i);
                    for (int j = 0; j < LEVEL; j++) {
                        for (int k = 0; k < HOUR; k++) {
                            NcVarPojo varPojo = new NcVarPojo();
                            varPojo.setLat(ncPojo.getLat());
                            varPojo.setLon(ncPojo.getLon());
                            varPojo.setTime(k);
                            varPojo.setCdnId(ncPojo.getId());
                            String spec= null;

                            StringBuilder specBuilder = new StringBuilder(Strings.EMPTY)
                                    .append(varPojo.getTime())
                                    .append(":")
                                    .append(varPojo.getTime())
                                    .append(",");
                            if (levelFlag){
                                varPojo.setLevel(j);
                                specBuilder.append(varPojo.getLevel())
                                           .append(":")
                                           .append(varPojo.getLevel())
                                           .append(",");
                            }

                            spec=specBuilder
                                       .append(varPojo.getLat())
                                       .append(":")
                                       .append(varPojo.getLat())
                                       .append(",")
                                       .append(varPojo.getLon())
                                       .append(":")
                                       .append(varPojo.getLon())
                                       .toString();
                            Array read = variable.read(spec);
                            Float var = null;
                            if (!read.toString().contains(",")){
                                var = Float.valueOf(read.toString());
                            }
                            varPojo.setValue(var);
                            results.add(varPojo);
                        }
                    }
                }
                ncBaseMapper=getMapperByFullName(fullNameEscaped);
                //分割一下免得sql语句超出长度了
                List<List<NcVarPojo>> lists = StreamUtil.splitList(results, 5000);
                for (int i = 0; i < lists.size(); i++) {
                    List<NcVarPojo> list = lists.get(i);
                    ncBaseMapper.insertBatch(list);
                }
            }
            nf.close();
        }catch (Exception e){
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();
        System.out.println(endTime-startTime);
        System.out.println("插入完成辣");
        return null;
    }
}
